-- SPDX-License-Identifier: GPL-3.0-or-later

--- 炉石传说卡牌基类
--- 
--- 独立于新月杀Card系统，建立炉石专用的卡牌体系
--- CardItem作为基类，随从(Minion)、法术(Spell)、武器(Weapon)等都继承自它
---
---@class Hearthstone.CardItem : Object
---@field public id integer @ 唯一ID
---@field public name string @ 卡牌名称
---@field public cost integer @ 法力值消耗
---@field public type string @ 卡牌类型："minion" | "spell" | "weapon" | "hero"
---@field public rarity string @ 稀有度："common" | "rare" | "epic" | "legendary"
---@field public card_class string @ 职业："neutral" | "warrior" | "mage" | "priest" 等
---@field public card_set string @ 卡牌集："basic" | "classic" | "expansion1" 等
---@field public collectible boolean @ 是否可收集（衍生物为false）
---@field public skills Skill[] @ 技能列表（复用新月杀Skill系统）
---@field public frozen boolean @ 冻结状态
---@field public package Package @ 卡牌所属的扩展包
local CardItem = class("Hearthstone.CardItem")

---@alias CardRarity string
CardItem.Common = "common"
CardItem.Rare = "rare" 
CardItem.Epic = "epic"
CardItem.Legendary = "legendary"

---@alias CardClass string
CardItem.Neutral = "neutral"
CardItem.Warrior = "warrior"
CardItem.Mage = "mage"
CardItem.Priest = "priest"
CardItem.Paladin = "paladin"
CardItem.Hunter = "hunter"
CardItem.Rogue = "rogue"
CardItem.Shaman = "shaman"
CardItem.Warlock = "warlock"
CardItem.Druid = "druid"
CardItem.DemonHunter = "demonhunter"

---@alias CardType string
CardItem.TypeMinion = "minion"
CardItem.TypeSpell = "spell"
CardItem.TypeWeapon = "weapon"
CardItem.TypeHero = "hero"

---@alias CardSet string
CardItem.SetBasic = "basic"
CardItem.SetClassic = "classic"
CardItem.SetExpansion1 = "expansion1"
CardItem.SetBattlegrounds = "battlegrounds"

--- 构造函数
---@param name string @ 卡牌名称
---@param cost integer @ 法力值消耗
---@param card_type string @ 卡牌类型
---@param rarity string @ 稀有度
---@param card_class string @ 职业
---@param card_set string @ 卡牌集
---@param collectible boolean @ 是否可收集
function CardItem:initialize(name, cost, card_type, rarity, card_class, card_set, collectible)
  self.name = name
  self.cost = cost or 0
  self.type = card_type or CardItem.TypeMinion
  self.rarity = rarity or CardItem.Common
  self.card_class = card_class or CardItem.Neutral
  self.card_set = card_set or CardItem.SetBasic
  self.collectible = collectible ~= false -- 默认可收集
  self.frozen = false
  self.id = 0 -- 由Engine分配
  self.skills = {}
  self.package = nil -- 由Package设置
end


local CBOR_TAG_CARD = 30001

-- 为了节约 不要用string当key
local CBOR_CARD_KEY_NAME = 12
local CBOR_CARD_KEY_COST = 13
local CBOR_CARD_KEY_ATK = 14
local CBOR_CARD_KEY_HP = 15
local CBOR_CARD_KEY_CARD_CLASS = 16
local CBOR_CARD_KEY_CARD_SET = 17
local CBOR_CARD_KEY_COLLECTIBLE = 18  
local CBOR_CARD_KEY_FROZEN = 19
local CBOR_CARD_KEY_VIRT_ID = 20
local CBOR_CARD_KEY_MARK = 21



function CardItem:__tocbor()
  if self.id ~= 0 then
    return cbor.encode(cbor.tagged(CBOR_TAG_CARD, self.id))
  else
    return cbor.encode(cbor.tagged(
      CBOR_TAG_CARD,
      {
        [CBOR_CARD_KEY_NAME] = self.name,
        [CBOR_CARD_KEY_COST] = self.cost,
        [CBOR_CARD_KEY_HP] = self.hp,
        [CBOR_CARD_KEY_ATK] = self.atk,
        [CBOR_CARD_KEY_CARD_CLASS] = self.card_class,
        [CBOR_CARD_KEY_CARD_SET] = self.card_set,
        [CBOR_CARD_KEY_COLLECTIBLE] = self.collectible,
        [CBOR_CARD_KEY_FROZEN] = self.frozen,
       
      }
    ))
  end
end

function CardItem:__tostring()
  return "<CardItem " .. self.name .. ">"
end

--- 克隆卡牌
---@param new_name string? @ 新名称，用于衍生卡牌
---@return CardItem
function CardItem:clone(new_name)
  local cloned = self.class:new(
    new_name or self.name,
    self.cost,
    self.type,
    self.rarity,
    self.card_class,
    self.card_set,
    self.collectible
  )
  
  -- 复制技能
  cloned.skills = {}
  for _, skill in ipairs(self.skills) do
    table.insert(cloned.skills, skill)
  end
  
  return cloned
end

--- 添加技能
---@param skill Skill @ 要添加的技能
function CardItem:addSkill(skill)
  table.insert(self.skills, skill)
end

--- 检查是否有指定技能
---@param skill_name string @ 技能名称
---@return boolean
function CardItem:hasSkill(skill_name)
  for _, skill in ipairs(self.skills) do
    if skill.name == skill_name then
      return true
    end
  end
  return false
end

--- 获取技能
---@param skill_name string @ 技能名称
---@return Skill?
function CardItem:getSkill(skill_name)
  for _, skill in ipairs(self.skills) do
    if skill.name == skill_name then
      return skill
    end
  end
  return nil
end

--- 检查是否为指定类型
---@param card_type string @ 卡牌类型
---@return boolean
function CardItem:isType(card_type)
  return self.type == card_type
end

--- 检查是否为指定职业
---@param card_class string @ 职业
---@return boolean
function CardItem:isClass(card_class)
  return self.card_class == card_class
end

--- 检查是否为指定稀有度
---@param rarity string @ 稀有度
---@return boolean
function CardItem:isRarity(rarity)
  return self.rarity == rarity
end

--- 检查是否为指定卡牌集
---@param card_set string @ 卡牌集
---@return boolean
function CardItem:isSet(card_set)
  return self.card_set == card_set
end

--- 获取卡牌描述（用于显示）
---@param lang string? @ 语言
---@return string
function CardItem:getDescription(lang)
  lang = lang or "zh_CN"
  return Fk:translate(":" .. self.name, lang) or self.name
end

return CardItem
